/*  
 * Copyright 2007 MBARI 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */
package org.mbari.timeline.swing;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Comparator;
import java.util.EventListener;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;

import org.mbari.timeline.DateUtil;
import org.mbari.timeline.model.MultipartEvent;

import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.ObservableElementList;
import ca.odell.glazedlists.SortedList;
import ca.odell.glazedlists.ObservableElementList.Connector;
import ca.odell.glazedlists.swing.EventTableModel;
import ca.odell.glazedlists.swing.TableComparatorChooser;

import com.domainlanguage.time.Duration;
import com.domainlanguage.time.TimePoint;

/** 
 * @author Andrew Chase
 */
@SuppressWarnings("serial")
public class TwoPartEventTable extends JTable{
	private final EventList<MultipartEvent> multipartEvents;
	public TwoPartEventTable(){
		super();
        multipartEvents = new BasicEventList<MultipartEvent>();
        
        final SortedList<MultipartEvent> sortedList = new SortedList<MultipartEvent>(multipartEvents,
            new Comparator<MultipartEvent>() {
				public int compare(MultipartEvent o1, MultipartEvent o2) {
					int result = o1.getTime().compareTo(o2.getTime());
					if(result != 0) return result;
					return o1.getDuration().compareTo(o2.getDuration());
				}
            });
        
        Connector<MultipartEvent> connector = new ObservableElementList.Connector<MultipartEvent>(){
            private ObservableElementList<MultipartEvent> theListToNotify;
            public EventListener installListener(final MultipartEvent event) {
                PropertyChangeListener propertyChangeListener = new PropertyChangeListener(){
                    public void propertyChange(PropertyChangeEvent evt) {
                        theListToNotify.elementChanged(event);
                    }
                };
                event.addPropertyChangeListener(propertyChangeListener);
                return propertyChangeListener;
            }
            public void setObservableElementList(ObservableElementList<MultipartEvent> list) {
                theListToNotify = list;
            }
            public void uninstallListener(MultipartEvent event, EventListener listener) {
                if(!(listener instanceof PropertyChangeListener)){
                    System.err.println("Wrong type property change listener trying to be removed...");
                }
                event.removePropertyChangeListener((PropertyChangeListener)listener);
            }
        };
        ObservableElementList<MultipartEvent> observableElementList = //
            new ObservableElementList<MultipartEvent>(sortedList, connector);
        
        final EventTableModel<MultipartEvent> tableModel = //
            new EventTableModel<MultipartEvent>(observableElementList, new TwoPartEventTableFormat()); 
                
        this.setModel(tableModel);
        @SuppressWarnings("unused") //makes the columns in the table sortable
		TableComparatorChooser chooser = new TableComparatorChooser<MultipartEvent>(this, sortedList, true);
	}

	public void addEvent(MultipartEvent event){
		multipartEvents.add(event);
	}
	
	public static void main(String[] args){
		TimePoint start = DateUtil
				.ansiStandardDateStringToDate("20070707-00:00:00");

		MultipartEvent event1 = MultipartEvent.twoPartEvent( //
				start.plus(Duration.days(2).plus(Duration.hours(3))), //
				Duration.minutes(35), Duration.minutes(180));
		event1.setName("Test Event 1");
		MultipartEvent event2 = MultipartEvent.twoPartEvent(start.plus(Duration
				.days(5)), // 
				Duration.minutes(60), Duration.days(1));
		event2.setName("Test Event 2");
		
		TwoPartEventTable table = new TwoPartEventTable();
		table.addEvent(event1);
		table.addEvent(event2);
		
		JScrollPane pane = new JScrollPane(table);
		
		JFrame frame = new JFrame("Test TwoPartEventTable");
		frame.getContentPane().add(pane);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setBounds(20, 50, 300, 300);
		frame.setVisible(true);
	}
}
